home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1992 Eric R. Smith. All rights reserved.
- * Redistribution is permitted only if the distribution
- * is not for profit, and only if all documentation
- * (including, in particular, the file "copying")
- * is included in the distribution in unmodified form.
- * THIS PROGRAM COMES WITH ABSOLUTELY NO WARRANTY, NOT
- * EVEN THE IMPLIED WARRANTIES OF MERCHANTIBILITY OR
- * FITNESS FOR A PARTICULAR PURPOSE. USE AT YOUR OWN
- * RISK.
- */
- #include "xgem.h"
- #include <osbind.h>
- #include <ctype.h>
- #include <stdlib.h>
- #include "twdefs.h"
- #include "twproto.h"
-
- /*
- * global variables for any GEM/AES application
- */
-
- /* VDI physical and virtual workstation handles */
- int phys_handle, vdi_handle = -1;
-
- /* AES application ID */
- int gl_apid;
-
- /* system character size */
- int gl_hchar, gl_wchar, gl_wbox, gl_hbox;
-
- /* size of the desktop area */
- int xdesk, ydesk, hdesk, wdesk;
-
- /* number of fonts available */
- int gl_numfonts = 1;
-
- /* rectangle we're watching for events */
- int gl_rx, gl_ry, gl_rw, gl_rh, gl_rstate;
-
- /* number of planes on screen */
- int gl_screenplanes;
-
- /*
- * global variables used by the xgem library
- */
-
- int gl_button; /* button state */
- int gl_done; /* set when the user wants to quit */
- long gl_timer; /* how many milliseconds before evnt_loop
- times out */
- void (*fn_timeout)(); /* what to do when a time out occurs */
- void (*fn_message)(); /* function for handling non-standard messages */
- void (*fn_mouse)(); /* mouse handler */
- int (*fn_key)(); /* default keyboard handler */
- void (*fn_rect)(); /* handler for rectangle events */
-
- /* variable that tells us about GDOS
- * 0: no GDOS
- * 1: old GDOS, or a clone
- * 2: FontGDOS
- * 3: FSMGDOS
- */
-
- #define GDOS 1
- #define FontGDOS 2
- #define FSMGDOS 3
- int gdos_active;
-
- /*
- * local variables
- */
-
- static int msgbuff[8]; /* AES message buffer */
- static int hidden; /* mouse hidden? */
-
-
- /*
- * some misc. utilities
- */
-
- void
- hide_mouse()
- {
- if (!hidden) {
- graf_mouse(M_OFF, 0x0L);
- hidden = TRUE;
- }
- }
-
- void
- show_mouse()
- {
- if (hidden) {
- graf_mouse(M_ON, 0x0L);
- hidden = FALSE;
- }
- }
-
- /* set clipping rectangle */
-
- static int clip[4];
-
- void set_clip(x,y,w,h)
- int x,y,w,h;
- {
- clip[0] = x;
- clip[1] = y;
- clip[2] = clip[0]+w-1;
- clip[3] = clip[1]+h-1;
- vs_clip(vdi_handle, 1, clip);
- }
-
- /*
- * Call this function to turn clipping off.
- */
-
- void
- reset_clip()
- {
- vs_clip(vdi_handle, 0, clip);
- clip[0] = clip[1] = clip[2] = clip[3] = -1;
- }
-
- static void
- handle_key(code, shift)
- int code, shift;
- {
- if (menu_key(code, shift)) {
- return;
- }
- if (window_key(code, shift)) {
- return;
- }
- if (fn_key && (*fn_key)(code))
- return;
- }
-
- static void
- handle_click(mclicks, mx, my, mshift, mbutton)
- int mclicks, mx, my, mshift, mbutton;
- {
- extern int window_click();
-
- if (window_click(mclicks, mx, my, mshift, mbutton))
- return;
- if (fn_mouse)
- (*fn_mouse)(mclicks, mx, my, mshift, mbutton);
- }
-
- /*
- * main event loop for most applications
- */
-
- void
- evnt_loop()
- {
- int event;
- int msx, msy, mbutton, mshift, mbreturn;
- int keycode;
- int evnt_type;
- extern void handle_menu();
- int gx, gy, gw, gh;
- int checkmenu = 0;
-
- gl_done = FALSE;
- do {
- evnt_type = MU_MESAG | MU_BUTTON | MU_KEYBD;
- if (fn_timeout) evnt_type |= MU_TIMER;
- if (fn_rect) evnt_type |= MU_M1;
- if (checkmenu && gl_topwin && gl_topwin->menu &&
- (gl_topwin->wi_handle > 0) &&
- (gl_topwin->wi_kind & INFO)) {
- evnt_type |= MU_M2;
- gx = gl_topwin->wi_x;
- gy = gl_topwin->wi_y - gl_hbox;
- gw = strlen(gl_topwin->infostr)*gl_wchar;
- if (gw > gl_topwin->wi_w)
- gw = gl_topwin->wi_w;
- gh = gl_hbox;
- } else {
- gx = gy = gw = gh = 0;
- }
- event = evnt_multi(evnt_type,
- 0x0101, 0x0003, 0x0000,
- gl_rstate,gl_rx,gl_ry,gl_rw,gl_rh,
- 0,gx,gy,gw,gh,
- msgbuff,
- gl_timer,
- &msx, &msy, &mbutton, &mshift,
- &keycode,
- &mbreturn);
-
- if (event & MU_MESAG) {
- switch (msgbuff[0]) {
- case MN_SELECTED:
- handle_menu(msgbuff[3], msgbuff[4]);
- break;
- case WM_REDRAW:
- case WM_TOPPED:
- case WM_CLOSED:
- case WM_FULLED:
- case WM_ARROWED:
- case WM_HSLID:
- case WM_VSLID:
- case WM_SIZED:
- case WM_MOVED:
- handle_window(msgbuff);
- break;
- default:
- if (fn_message)
- (*fn_message)(msgbuff);
- break;
- }
- }
-
- /* if we got a message, the top window may have been changed,
- * so ignore drop down menu events
- */
- else if (event & MU_M2) {
- if (msx >= gx && msx < gx+gw &&
- msy >= gy && msy < gy+gh) {
- dropdown_menu(gl_topwin->menu, gx, gy);
- }
- checkmenu = 0;
- } else {
- checkmenu = 1;
- }
-
- /* if we are "pointing to type", then set the focus window appropriately */
- if (point_to_type) {
- WINDOW *newfocus;
- TEXTWIN *oldt, *newt;
-
- oldt = newt = 0;
- newfocus = find_window(msx, msy);
- if (!newfocus) newfocus = gl_topwin;
- if (newfocus != focuswin) {
- if (focuswin && focuswin->wtype == TEXT_WIN) {
- oldt = focuswin->extra;
- curs_off(oldt);
- }
- if (newfocus && newfocus->wtype == TEXT_WIN) {
- newt = newfocus->extra;
- curs_off(newt);
- }
- focuswin = newfocus;
- if (oldt) {
- curs_on(oldt);
- refresh_textwin(oldt);
- }
- if (newt) {
- curs_on(newt);
- refresh_textwin(newt);
- }
- }
- }
- else
- focuswin = gl_topwin;
-
- if (event & MU_BUTTON) {
- handle_click(mbreturn, msx, msy, mshift, mbutton);
- }
-
- if (event & MU_KEYBD) {
- handle_key(keycode, mshift);
- }
-
- if (event & MU_M1) {
- gl_rstate = !gl_rstate;
- (*fn_rect)(msx, msy);
- }
-
- if (event & MU_TIMER) {
- (*fn_timeout)();
- }
- } while (!gl_done);
- }
-
- static int lasttextcolor, lastfillcolor, lastwrmode, lastheight, lastfont;
- static int laststyle, lastindex;
- static int lasteffects;
-
- void
- open_vwork()
- {
- int work_in[11];
- int work_out[57];
- int i;
-
- /* open a virtual workstation */
- if (vdi_handle > 0) /* workstation already open */
- return;
- for (i = 1; i < 10; i++)
- work_in[i] = 1;
- work_in[0] = Getrez()+2;
- work_in[10] = 2;
- vdi_handle = phys_handle;
- v_opnvwk(work_in, &vdi_handle, work_out);
- lastheight = lasttextcolor = lastfillcolor = lastwrmode = -1;
- lasteffects = 0;
- lastindex = laststyle = lastfont = 1;
- gl_numfonts = work_out[10];
- if (gdos_active)
- gl_numfonts += vst_load_fonts(vdi_handle, 0);
- vq_extnd(vdi_handle, 1, work_out);
- gl_screenplanes = work_out[4];
- }
-
- void
- close_vwork()
- {
- if (vdi_handle > 0) {
- if (gdos_active)
- vst_unload_fonts(vdi_handle, 0);
- v_clsvwk(vdi_handle);
- }
- vdi_handle = -1;
- }
-
- void
- init_gem()
- {
- extern int vq_gdos();
- extern short _app;
- long gdosvers;
-
- gl_apid = appl_init();
- phys_handle = graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox);
- wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
- gdos_active = vq_gdos();
- if (gdos_active) {
- gdosvers = vq_vgdos();
- if (gdosvers == GDOS_NONE) {
- gdos_active = 0;
- } else if (gdosvers == GDOS_FSM) {
- gdos_active = FSMGDOS;
- } else if (gdosvers == GDOS_FNT) {
- gdos_active = FontGDOS;
- } else {
- gdos_active = GDOS;
- }
- }
-
- open_vwork();
- if (_app) {
- graf_mouse(ARROW, 0L);
- }
- }
-
- /*
- * exit a gem application
- */
-
- void
- exit_gem(status)
- int status;
- {
- wind_update(0); /* just in case */
- end_windows();
- close_vwork();
- appl_exit();
- exit(status);
- }
-
- /*
- * some more miscellaneous utility routines
- */
-
- void
- set_fillcolor(col)
- int col;
- {
- if (col == lastfillcolor) return;
- vsf_color(vdi_handle, col);
- lastfillcolor = col;
- }
-
- void
- set_textcolor(col)
- int col;
- {
- if (col == lasttextcolor) return;
- vst_color(vdi_handle, col);
- lasttextcolor = col;
- }
-
- void
- set_texteffects(effects)
- int effects;
- {
- if (effects == lasteffects) return;
- lasteffects = vst_effects(vdi_handle, effects);
- }
-
- void
- set_wrmode(mode)
- int mode;
- {
- if (mode == lastwrmode) return;
- vswr_mode(vdi_handle, mode);
- lastwrmode = mode;
- }
-
- static int
- is_fsm_font(font)
- int font;
- {
- int i;
-
- for (i = 0; i < gl_numfonts; i++) {
- if (fontdesc[i].fontidx == font)
- return fontdesc[i].isfsm;
- }
- return 0;
- }
-
- /* This function sets both the font and the size (in points).
- */
-
- void
- set_font(font, height)
- int font, height;
- {
- int cw, ch, bw, bh;
-
- if (font != lastfont) {
- vst_font(vdi_handle, font);
- lastfont = font;
- lastheight = height-1;
- }
- if (height != lastheight) {
- if (gdos_active == FSMGDOS && is_fsm_font(font)) {
- lastheight = vst_arbpt(vdi_handle, height,
- &cw, &ch, &bw, &bh);
- } else {
- lastheight = vst_point(vdi_handle, height, &cw, &ch,
- &bw, &bh);
- }
- }
- }
-
- void
- set_fillstyle(style, index)
- int style, index;
- {
- if (laststyle != style)
- laststyle = vsf_interior(vdi_handle, style);
-
- if (index != lastindex)
- lastindex = vsf_style(vdi_handle, index);
- }
-